package cn.bigfire.wzdj.util.protode;

import cn.hutool.core.util.CharUtil;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 *
 * 文心一言的优化建议
 * https://yiyan.baidu.com/share/BEHSS3XjQ6?utm_invite_code=5grOLtTDhg6LMxzoCqlljg%3D%3D&utm_name=5aSn54GreXpz&utm_fission_type=common
 */
public class DataChecker {
    public static boolean isProtobufData(byte[] data) {
        if (data == null || data.length < 2) {
            return false;
        }

        int tag = data[0] & 0xFF;
        int fieldNumber = tag >>> 3;//取前5位
        int wireType = tag & 0x07; // 取后3位

        if (fieldNumber < 1) {
            return false;
        }

        int length = decodeVarint(Arrays.copyOfRange(data, 1, data.length));
        if (length < 0 || length > data.length - 1 - varintLength(data[1])) {
            return false;
        }

        byte[] value = Arrays.copyOfRange(data, 1 + varintLength(data[1]), 1 + varintLength(data[1]) + length);

        // 尝试将 value 作为 UTF-8 字符串解码
        try {
            String str = new String(value, "UTF-8");
            // 这里可以添加额外的检查，例如判断字符串是否包含有效的 ASCII 字符
            // 或者使用正则表达式匹配预期的字符串模式
            if (isValidString(str)) {
                return false; // 可能是字符串数据
            }
        } catch (Exception e) {
            // 解码失败，可能是 Protobuf 对象数据
        }

        // 其他启发式规则检查（可选）
        // ...

        return true; // 默认为 Protobuf 对象数据
    }

    // 变长整数解码（简化版）
    public static int decodeVarint(byte[] data) {
        int result = 0;
        int shift = 0;
        for (byte b : data) {
            int value = b & 0x7F;
            result |= value << shift;
            if ((b & 0x80) == 0) {
                break;
            }
            shift += 7;
        }
        return result;
    }

    // 计算变长整数的字节长度（简化版）
    public static int varintLength(byte b) {
        if ((b & 0x80) == 0) {
            return 1;
        }
        if ((b & 0xC0) == 0x80) {
            return 2;
        }
        if ((b & 0xE0) == 0xC0) {
            return 3;
        }
        if ((b & 0xF0) == 0xE0) {
            return 4;
        }
        if ((b & 0xF8) == 0xF0) {
            return 5;
        }
        return 6; // 理论上最多6个字节，但 Protobuf 中不太可能使用这么多
    }

    // 额外的字符串有效性检查（示例）
    private static boolean isValidString(String str) {
        // 这里可以根据需要添加具体的检查逻辑
        // 例如，判断字符串是否只包含字母、数字、空格和标点符号等
        return isPrintableString(str);
    }

    // 检查字符串是否只包含可打印字符
    private static boolean isPrintableString(String str) {
        for (int i = 0; i < str.length(); i++) {
            if (!CharUtil.isAsciiPrintable(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }


    public static boolean isValidUTF8(String input) {
        // 将字符串转换为字节数组
        byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
        try {
            // 尝试解码回字符串
            String decoded = new String(bytes, StandardCharsets.UTF_8);
            return decoded.equals(input);// 比较解码后的字符串与原字符串
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) {
        String testString1 = "Hello, 世界"; // 包含UTF-8字符
        String testString2 = "Invalid \uD83D"; // 包含无效字符

        System.out.println(testString1 + " is valid UTF-8: " + isValidUTF8(testString1));
        System.out.println(testString2 + " is valid UTF-8: " + isValidUTF8(testString2));
    }


}
